package com.xcm.controller;

import com.google.common.collect.Maps;
import com.xcm.constant.ClientConstant;
import com.xcm.constant.DateFormatConstant;
import com.xcm.constant.ResponseConstant;
import com.xcm.exception.ControllerException;
import com.xcm.model.JsonResponse;
import com.xcm.model.TbDeviceInfo;
import com.xcm.model.TbDeviceUpgrade;
import com.xcm.model.dto.NewestProgramDTO;
import com.xcm.service.ClientService;
import com.xcm.service.DeviceInfoService;
import com.xcm.util.DateUtils;
import com.xcm.util.HttpUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 终端与服务端交互,接口使用Key校验
 * 接受客户端上传的终端数据
 */
@Controller
@RequestMapping(value = "/client")
public class ClientContoller {
	private static Logger logger = LoggerFactory.getLogger(ClientContoller.class);
	@Autowired
	private DeviceInfoService deviceInfoService;
	@Autowired
	private ClientService clientService;

	/**
	 * 终端调用接口上报终端数据
	 */
	@ResponseBody
	@RequestMapping(value = "/report")
	public Object report(TbDeviceInfo deviceInfo, HttpServletRequest request) {
		//提示信息Map
		Map<String, Object> msgMap = Maps.newHashMap();
		//验证参数
		String mac = deviceInfo.getDeviceMac();
		if (StringUtils.isBlank(deviceInfo.getDeviceNum()) || StringUtils.isBlank(mac) || StringUtils.isBlank(deviceInfo.getDeviceSoftVer()) ||
				StringUtils.isBlank(deviceInfo.getDeviceModel())) {
			msgMap.put(ClientConstant.CODE, ClientConstant.CODE_FAIL);
			msgMap.put(ClientConstant.MSG, ClientConstant.MSG_PARAM_ERROR);
			return msgMap;
		}
		//验证参数长度
		if (deviceInfo.getDeviceNum().length() > 50 || deviceInfo.getDeviceSoftVer().length() > 32 || deviceInfo.getDeviceModel().length() > 64) {
			msgMap.put(ClientConstant.CODE, ClientConstant.CODE_FAIL);
			msgMap.put(ClientConstant.MSG, ClientConstant.MSG_PARAM_SIZE_ERROR);
			return msgMap;
		}
		//获取ip地址和位置信息
		String remortIP = HttpUtils.getRemortIP(request);
		deviceInfo.setDeviceIp(remortIP);
		try {
			//根据mac获取终端信息
			TbDeviceInfo olddeviceInfo = deviceInfoService.getDeviceInfoByMac(mac);
			//如果终端信息不存在，新增终端信息
			if (olddeviceInfo == null) {
				deviceInfoService.saveDeviceInfo(deviceInfo);
			} else {
				//如果终端信息存在，更新终端信息
				deviceInfoService.updateDeviceInfo(deviceInfo, olddeviceInfo);
			}
		} catch (Exception e) {
			logger.error("ClientContoller report 上报终端数据失败：" + e.getMessage());
			msgMap.put(ClientConstant.CODE, ClientConstant.CODE_FAIL);
			msgMap.put(ClientConstant.MSG, ClientConstant.MSG_ERROR);
			return msgMap;
		}
		msgMap.put(ClientConstant.CODE, ClientConstant.CODE_SUCCESS);
		msgMap.put(ClientConstant.MSG, ClientConstant.MSG_SUCCESS);
		return msgMap;
	}

	/**
	 * 获取最新设置数据
	 */
	@ResponseBody
	@RequestMapping(value = "/getStates")
	public Object getStates(String mac, String version) {
		if (StringUtils.isBlank(mac) || StringUtils.isBlank(version)) {
			return new ControllerException("输入参数不能为空");
		}
		TbDeviceInfo deviceInfo = deviceInfoService.getDeviceInfoByMac(mac);
		if (deviceInfo == null) {
			return new ControllerException("没有查询到终端信息");
		}
		try {
			return clientService.getStates(mac, version, deviceInfo);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("ClientContoller getStates 获取最新设置数据失败：" + e.getMessage());
			return new ControllerException("获取最新设置数据失败");
		}
	}

	/**
	 * 获取最新广告数据
	 */
	@ResponseBody
	@RequestMapping(value = "getNewestProgram")
	public Object getNewestProgram(String mac, String version) {
		//验证mac地址是否为空
		if (StringUtils.isBlank(mac)) {
			return new JsonResponse(ResponseConstant.CODE_FAIL, "mac地址不能为空");
		}
		NewestProgramDTO newestProgramDTO = new NewestProgramDTO();
		//给NewestProgramDTO最新广告数据设置值
		String msg = clientService.getNewestProgram(mac, version, newestProgramDTO);
		//如果返回提示信息为空，返回最新广告数据
		if (StringUtils.isBlank(msg)) {
			return newestProgramDTO;
		} else {
			//否则，返回提示信息
			return new JsonResponse(ResponseConstant.CODE_FAIL, msg);
		}
	}

	/**
	 * 获取应用升级数据
	 */
	@ResponseBody
	@RequestMapping(value = "/getUpdateApk")
	public Object getUpdateApk(String model, String mac, String version) {
		if (StringUtils.isBlank(model)) {
			return new JsonResponse(ResponseConstant.CODE_FAIL, "对应机型不能为空");
		}
		if (StringUtils.isBlank(version)) {
			return new JsonResponse(ResponseConstant.CODE_FAIL, "版本号不能为空");
		}
		//获取终端升级信息
		TbDeviceUpgrade deviceUpgrade = clientService.getDeviceUpgrade(model, mac);
		if (deviceUpgrade == null || version.equals(deviceUpgrade.getVersionName())) {
			return new JsonResponse(ResponseConstant.CODE_FAIL, "数据未更新");
		}
		return deviceUpgrade;
	}

	/**
	 * 上报广告数据的下载状态
	 */
	@ResponseBody
	@RequestMapping(value = "setDownload")
	public Object setDownload(String mac, String playJson, String downloadJson, Integer state) {
		//验证参数
		if (StringUtils.isBlank(mac) || StringUtils.isBlank(playJson) || StringUtils.isBlank(downloadJson) || state == null) {
			return new JsonResponse(ResponseConstant.CODE_FAIL, "参数不能为空");
		}
		try {
			clientService.setDownload(mac, playJson, downloadJson, state);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("ClientContoller setDownload 上报广告数据的下载状态失败：" + e.getMessage());
			return new ControllerException("上报广告数据的下载状态失败");
		}
		return "";
	}

	/**
	 * 上传终端日志
	 */
	@ResponseBody
	@RequestMapping(value = "uploadLog")
	public Object uploadLog(String mac, String name, String url) {
		//验证参数是否为空
		if (StringUtils.isBlank(mac) || StringUtils.isBlank(name) ||
				StringUtils.isBlank(url)) {
			return new JsonResponse(ResponseConstant.CODE_FAIL, "参数不能为空");
		}
		//验证参数长度
		if ((name.length() > 64 ) || (url.length() > 256)) {
			return new JsonResponse(ResponseConstant.CODE_FAIL, "参数长度错误");
		}
		try {
			clientService.uploadLog(mac, name, url);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("ClientContoller uploadLog 上传终端日志失败：" + e.getMessage());
			return new ControllerException("上传终端日志失败");
		}
		return "";
	}

	/**
	 * 设置机器码
	 */
	@ResponseBody
	@RequestMapping(value = "setDeviceNum")
	public Object setDeviceNum(String mac, String deviceNum) {
		if (StringUtils.isBlank(mac) || StringUtils.isBlank(deviceNum)) {
			return new JsonResponse(ResponseConstant.CODE_FAIL, "输入参数不能为空");
		}

		if (deviceNum.length() > 50) {
			return new JsonResponse(ResponseConstant.CODE_FAIL, "输入参数长度有误");
		}
		try {
			clientService.setDeviceNum(mac, deviceNum);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("ClientContoller setDeviceNum 设置机器码失败：" + e.getMessage());
			return new ControllerException("设置机器码失败");
		}
		return "";
	}

	/**
	 * 设置音量
	 */
	@ResponseBody
	@RequestMapping(value = "setVolume")
	public Object setVolume(String mac, Integer deviceVolume) {
		if (StringUtils.isBlank(mac) || deviceVolume == null) {
			return new JsonResponse(ResponseConstant.CODE_FAIL, "输入参数不能为空");
		}
		if (deviceVolume < 0 || deviceVolume > 10) {
			return new JsonResponse(ResponseConstant.CODE_FAIL, "输入参数长度有误");
		}
		try {
			clientService.setVolume(mac, deviceVolume);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("ClientContoller setVolume 设置音量失败：" + e.getMessage());
			return new ControllerException("设置音量失败");
		}
		return "";
	}

	/**
	 * 设置开关机
	 */
	@ResponseBody
	@RequestMapping(value = "setTimer")
	public Object setTimer(String mac, Integer useTimer, String bootTime, String offTime) {
		if (StringUtils.isBlank(mac) || useTimer == null) {
			return new JsonResponse(ResponseConstant.CODE_FAIL, "输入参数不能为空");
		}
		try {
			Long longBootTime = DateUtils.stringTimeToLongTimeStamp(bootTime, DateFormatConstant.DATE_ONLYHM_24);
			Long longOffTime = DateUtils.stringTimeToLongTimeStamp(offTime,DateFormatConstant.DATE_ONLYHM_24);
			clientService.setTimer(mac, useTimer, longBootTime, longOffTime);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("ClientContoller setTimer 设置开关机失败：" + e.getMessage());
			return new ControllerException("设置开关机失败");
		}
		return "";
	}

}
